﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PriErp.Tools.Extensions
{
    /// <summary>
    /// 扩展类
    /// </summary>
    public static partial class PriErpExtension
    {
        /// <summary>
        /// 转换类型(是对应类型的转换，否则返回默认值)
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">转换值</param>
        /// <returns>返回新类型值</returns>
        static public T AsType<T>(this object obj)
        {
            return obj.AsType(default(T));
        }

        /// <summary>
        /// 转换类型(是对应类型的转换，否则返回默认值)
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">转换值</param>
        /// <param name="dVal">默认类型</param>
        /// <returns>返回新类型值</returns>
        static public T AsType<T>(this object obj, T dVal)
        {
            return obj is T ? (T)obj : dVal;
        }

        /// <summary>
        /// 转换为String(为空则返回Null)
        /// </summary>
        /// <param name="obj">转换值</param>
        /// <returns>返回字符串</returns>
        static public string ToStringOrNull(this object obj)
        {
            return obj == null ? null : obj.ToString();
        }

        /// <summary>
        /// 转换为String(为空则返回String.Empty)
        /// </summary>
        /// <param name="obj">转换值</param>
        /// <returns>返回字符串</returns>
        static public string ToStringEmpty(this object obj)
        {
            return obj == null ? string.Empty : obj.ToString();
        }

        /// <summary>
        /// 判断是否为空
        /// </summary>
        /// <param name="str">指定字符串</param>
        /// <returns>返回结果是否</returns>
        static public bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }

        /// <summary>
        /// 字符串Trim(空则返回空)
        /// </summary>
        /// <param name="sVal">需处理的字符串</param>
        /// <returns>返回处理后的字符串</returns>
        static public string TryTrim(this string sVal)
        {
            return sVal == null ? sVal : sVal.Trim();
        }

        /// <summary>
        /// 转换为Byte类型
        /// </summary>
        /// <param name="sVal">需要转换的字符串</param>
        /// <param name="dVal">默认值</param>
        /// <returns>返回Byte</returns>
        static public Byte ToByte(this string sVal, Byte dVal)
        {
            Byte tmp ;
            if (!Byte.TryParse(sVal.TryTrim(), out tmp))
                tmp = dVal;
            return tmp;
        }

        /// <summary>
        /// 转换为Byte类型,默认为0
        /// </summary>
        /// <param name="sVal">需要转换的字符串</param>
        /// <returns>返回Byte</returns>
        static public Byte ToByte(this string sVal)
        {
            return sVal.ToByte(0);
        }

        /// <summary>
        /// 转换为bool类型
        /// </summary>
        /// <param name="sVal">需要转换的字符串</param>
        /// <param name="dVal">默认值</param>
        /// <returns>返回bool</returns>
        static public bool ToBoolean(this string sVal, bool dVal)
        {
            bool tmp;
            if (!bool.TryParse(sVal.TryTrim(), out tmp))
                tmp = dVal;
            return tmp;
        }

        /// <summary>
        /// 转换为bool类型(默认为false)
        /// </summary>
        /// <param name="sVal">需要转换的字符串</param>
        /// <returns>返回bool</returns>
        static public bool ToBoolean(this string sVal)
        {
            return sVal.ToBoolean(false);
        }

        /// <summary>
        /// 转换为时间格式(错误返回当前时间)
        /// </summary>
        /// <param name="sVal">需转换的字符串</param>
        /// <returns>返回转换后的DateTime值</returns>
        public static DateTime ToDateTime(this string sVal)
        {
            return sVal.ToDateTime(DateTime.Now);
        }

        /// <summary>
        /// 转换为时间格式
        /// </summary>
        /// <param name="sVal">需转换的字符串</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>返回转换后的DateTime值</returns>
        public static DateTime ToDateTime(this string sVal, DateTime defaultValue)
        {
            DateTime result;
            if (!DateTime.TryParse(sVal.TryTrim(), out result))
                result = defaultValue;
            return result;
        }

        /// <summary>
        /// 判断数值是否有效
        /// </summary>
        /// <param name="val">需判断的数值</param>
        /// <returns>返回是否有效</returns>
        public static bool HasValue(this double val)
        {
            return !(double.IsNaN(val) || double.IsInfinity(val));
        }

        /// <summary>
        /// 转换为Double类型(默认为0)
        /// </summary>
        /// <param name="sVal">需转换的默认值</param>
        /// <returns>返回转换后的Double值</returns>
        static public double ToDouble(this string sVal)
        {
            return sVal.ToDouble(0d);
        }

        /// <summary>
        /// 转换为Double类型
        /// </summary>
        /// <param name="sVal">需转换的字符串</param>
        /// <param name="dVal">默认值</param>
        /// <returns>返回转换后的Double值</returns>
        static public double ToDouble(this string sVal, double dVal)
        {
            double num;
            if (!double.TryParse(sVal.TryTrim(), out num))
                num = dVal;
            return num;
        }

        /// <summary>
        /// 转换为Int32类型(默认为0)
        /// </summary>
        /// <param name="sVal">需转换的字符串</param>
        /// <returns>返回转换后的Int32值</returns>
        static public int ToInt32(this string sVal)
        {
            return sVal.ToInt32(0);
        }

        /// <summary>
        /// 转换为Int32类型
        /// </summary>
        /// <param name="sVal">需转换的字符串</param>
        /// <param name="dVal">默认值</param>
        /// <returns>返回转换后的Int32值</returns>
        static public int ToInt32(this string sVal, int dVal)
        {
            int num;
            if (!int.TryParse(sVal.TryTrim(), out num))
                num = dVal;
            return num;
        }

        /// <summary>
        /// 转换为小数点后N(0~15)位
        /// </summary>
        /// <param name="dVal">数值</param>
        /// <param name="digits">N位</param>
        /// <returns>>返回(数值)小数点后N位</returns>
        public static double ToFN(this double dVal, int digits)
        {
            return Math.Round(dVal, digits);
        }

        /// <summary>
        /// 转换为小数点后2位
        /// </summary>
        /// <param name="dVal">数值</param>
        /// <returns>返回(数值)小数点后2位</returns>
        public static double ToF2(this double dVal)
        {
            return dVal.ToFN(2);
        }

        /// <summary>
        /// 格式化为万并转换为小数点后2位
        /// </summary>
        /// <param name="dVal">数值</param>
        /// <returns>返回(万)小数点后2位</returns>
        public static double To10KF2(this double dVal)
        {
            return Math.Round(dVal / 10000d, 2);
        }

        /// <summary>
        /// 格式化为(万元)显示
        /// </summary>
        /// <param name="dVal">数值</param>
        /// <returns>返回(万元)数值显示</returns>
        public static string To10KMoney(this double dVal)
        {
            if (double.IsInfinity(dVal) || double.IsNaN(dVal))
                return "--";
            dVal /= 10000d;
            return dVal.ToString("###,##0.##");
        }

        /// <summary>
        /// 格式化为(元)显示
        /// </summary>
        /// <param name="dVal">数值</param>
        /// <returns>返回(元)数值显示</returns>
        public static string ToMoney(this double dVal)
        {
            if (double.IsInfinity(dVal) || double.IsNaN(dVal))
                return "--";
            return dVal.ToString("###,##0.##");
        }
    }
}
